package org.lee.netty.sample;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;

import java.nio.charset.StandardCharsets;

/**
 * NettyServerHandler
 * 服务器处理器
 * 说明：
 * 1、定义一个Handler，需要继承netty规定好的某个HandlerAdapter
 * 2、这时自定义一个Handler，才能称为一个Handler
 *
 * @author dralee
 * @date 2022-01-01 16:58:24
 **/
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    // 数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // writeAndFlush 是write+flush
        // 将数据写入到缓存，并刷新
        // 一般讲，对发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端~ (>^ω^<)喵~".getBytes(StandardCharsets.UTF_8)));
    }

    // 处理异常，一般是要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    // 读取数据实际（这里可读取客户端发送的消息）
    // 1、ChannelHandlerContext ctx上下文对象，含有管道pipeline，通道channel，地址
    // 2、Object msg：就是客户端发送的数据 默认Object
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服务器读取线程：" + Thread.currentThread().getName());
        System.out.println("server ctx:" + ctx);
        System.out.println("channel与pipeline关系");
        Channel channel = ctx.channel();
        ChannelPipeline pipeline = channel.pipeline(); // 本质是一个双向链表，出栈入栈
        // 将msg转成一个ByteBuffer
        // ByteBuf是Netty提供的，不是NIO的ByteBuffer
        ByteBuf buffer = (ByteBuf) msg;
        System.out.println("客户端发送消息是：" + buffer.toString(StandardCharsets.UTF_8));
        System.out.println("客户端地址：" + ctx.channel().remoteAddress());
    }
}
